/*********************************************************************************
 *      Copyright:  (C) 2025 LingYun IoT System Studio
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2025年04月26日)
 *         Author:  Li Jiahui <2199250859@qq.com>
 *      ChangeLog:  1, Release initial version on "2025年04月26日 12时45分22秒"
 *                 
 ********************************************************************************/

#include <getopt.h>
#include <sys/time.h>

#include "pack.h"
#include "net_client.h"
#include "get_temp.h"
#include "sqlite3_handler.h"
#include "logger.h"



void print_usage(char *progname)
{
	log_info("%s usage:\n", progname);
	log_info("-i(--ipaddr):specify server IP address\n");
	log_info("-p(--port):specify server port\n");
	log_info("-h(--help):print this helo information\n");
	log_info("-d(--debug):running in debuf mode");
	log_info("-t(--interval):sepecify the time whe the data will be sent\n");
	return ;
}


int main(int argc,char **argv)
{
	int 			ch = -1;
	char 			*servip = NULL;
    int     		db_id;
    char    		data[1024];
    time_t 			last_time = 0;//记录上一次采样时间
    int 			has_sample = 0;
    time_t 			now_time = 0;	
	int				port = 0;
	int				interval = 0;
	pack_t			pack;
	char			buf[1024];
	sock_t			sock;
	int				log_size = 1024;
	char			*log_file = "test.log";
	int				log_level = LOG_LEVEL_INFO;
	int				rv = 0;
	time_t			current_time;
  	int				last_connectfd= - 1;
	sqlite3 		*db = NULL;
	char			pack_buf[1024];
	int				pack_bytes = 0;
	pack_proc_t		pack_proc = pack_data_segmented;
	//pack_proc_t   pack_proc = pack_json_message;
	//pack_proc_t  	pack_proc = pack_tlv_message;

	struct option 	opts[]={
		{"ipaddr", required_argument, NULL, 'i'},
		{"port", required_argument, NULL, 'p'},
		{"interval", required_argument, NULL, 't'},
		{"debug", no_argument, NULL, 'd'},
		{"help", no_argument, NULL, 'h'},
		{NULL, 0, NULL, 0}
	};

	while((ch=getopt_long(argc, argv, "i:p:t:hd", opts, NULL)) != -1)
	{
		switch(ch)
		{
			case 'i':
				servip = optarg;
				break;
			case 'p':
				port = atoi(optarg);
				break;
			case 't':
				interval = atoi(optarg);
				break;
			case 'd':
				log_file = "console";
				log_level = LOG_LEVEL_DEBUG;
				break;
			case 'h':
				print_usage(argv[0]);
				return 0;
		}
	}


	if(!servip || !port || !interval)
	{
		print_usage(argv[0]);
		return 0;
	}

	log_open(log_file, log_level , log_size, LOG_LOCK_DISABLE);

	//初始化socket
	if(socket_client_init(&sock, servip, port)!=0)
	{
		log_error("socket_client_init failure:%s\n", strerror(errno));
		return -1;
	}

	//初始化数据库
	if(init_db("temperature.db", &db)!=0)
	{
		log_error("init db failure:%s\n", strerror(errno));
		return -2;
	}
	

	while(1)
	{
		has_sample = 0;//标记采样状态，0：未采样

		//判断是否到采样时间
		now_time = time(NULL);//get time
		if( difftime(now_time, last_time) >= interval )
		{
			last_time = now_time;//updata last pack data time

			if( pack_data(&pack) !=0 )//get pack
			{
				log_debug("pack data failure!\n");
				continue;
			}
			
			pack_bytes = pack_proc(&pack, (uint8_t *)pack_buf, sizeof(pack_buf));//选择数据格式并打包

			log_info("pack data successfully:%s\n", buf);
			has_sample = 1;
		}
		
		//判断socket
		//socket_check(&sock);
		if( !socket_check(&sock) )//disconnected
		{
			log_warn("Disconnected,Try to reconnect...\n");

			//重连
			socket_close(&sock);
			if( socket_connect(&sock) < 0)
			{
				log_error("Failed to reconnect to server and data will save to database\n");

				if(has_sample)//有采样就存数据库
				{
					if(save_pack_to_db(db, &pack)!=0)
					{
						log_error("Failed to save data to the database.\n");
					}
					log_info("Data successfully stored in the database.\n");
				}

				continue;
			}
			log_info("Reconnected to server successfully!\n");
		}

		//执行下面的代表已连接服务器
		
		//有采样
		if(has_sample)
		{
			if(write(sock.fd, pack_buf, pack_bytes) < 0)//发送采样数据失败
			{
				log_error("Failed to send data to server.\n");

				//存入数据库
				if(save_pack_to_db(db, &pack)!=0)
				{
					log_error("Failed to save to the database.\n");
				}
				log_info("save data to database successfully.\n");
				
				continue;
			}

			log_info("Data sent to the server successfully!\n");
		}

		//没有采样则处理数据库里的内容
		if(fetch_first_pack(db, &pack, &db_id)==0)//有数据
		{
			pack_bytes = pack_proc(&pack, (uint8_t *)pack_buf, sizeof(pack_buf));

			log_info("Obtain the first piece of data:%s\n", pack_buf);

			if(write(sock.fd, pack_buf, pack_bytes) < 0)
			{
				log_error("Failed to send data:%s\n", strerror(errno));
			}
			else
			{
				log_info("Successfully sent database data!\n");

				if(delete_pack_by_id(db, db_id)!=0)//删除第一条数据
				{
					log_error("Delete data failure:%s\n", strerror(errno));
				}
				log_info("Successfully deleted the sent data.\n");
			}
		}
	
		usleep(100000);


	}

	sqlite3_close(db);
	socket_close(&sock);
	log_close();

	return 0;


}



